﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Xml.Linq;
using System.Collections;

namespace Smoo.FolderMonitor
{
    public class Lin2XmlFoldersRepository : Smoo.FolderMonitor.IFoldersRepository    
    {
        public string FileName { get; set; }
        private XDocument document;
        private IEnumerable<XElement> folders;

        public Lin2XmlFoldersRepository() : this(Globals.Lin2XmlFoldersRepositoryDataSource) { }

        public Lin2XmlFoldersRepository(string fileName)
        {
            FileName = fileName;
            LoadDocument(fileName);
        }

        private void LoadDocument(string path)
        {
            document = XDocument.Load(path);
            folders = document.Descendants("folders").Descendants();
        }

        public IQueryable<Folder> GetAll()
        {
            return folders
            .Select(element => new Folder
            {
                FriendlyName = element.Attribute("friendlyName").Value,
                Path = element.Attribute("path").Value
            })
            .AsQueryable();
        }

        public Folder GetFolder(string path)
        {
            var node = GetFolderNode(path);
            return node == null ? null : new Folder
            {
                FriendlyName = node.Attribute("friendlyName").Value,
                Path = node.Attribute("path").Value
            };
        }

        private XElement GetFolderNode(string path)
        {
            return folders.SingleOrDefault(f => f.Attribute("path").Value == path);
        }

        public bool CreateFolder(Folder folder)
        {
            try
            {
                var existingFolder = GetFolderNode(folder.Path);

                if (existingFolder != null)
                {
                    throw new InvalidOperationException("Path already exists");
                }

                folders.Last().AddAfterSelf(new XElement("folder",
                    new XAttribute("path", folder.Path),
                    new XAttribute("friendlyName", folder.FriendlyName)));
                document.Save(FileName);

                return true;
            }
            catch (Exception) 
            {
                return false;
            }
        }

        public bool ModifyFolder(Folder folder)
        {
            try
            {
                var node = GetFolderNode(folder.Path);
                node.Attribute("friendlyName").Value = folder.Path;
                document.Save(FileName);

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool DeleteFolder(string path)
        {
            try
            {
                var node = folders.SingleOrDefault(n => n.Attribute("path").Value == path);

                if (node != null)
                {
                    node.Remove();
                    document.Save(FileName);

                    return true;
                }
                else
                {
                    return false;
                }

            }
            catch (Exception)
            {
                return false;
            }
        }

    }
}
